<!--
 * @Author       : wfl
 * @LastEditors: qiye
 * @description  :
 * @updateInfo   :
 * @Date         : 2023-06-28 09:52:38
 * @LastEditTime: 2024-02-04 16:19:12
-->
<route lang="yaml">
meta:
  whiteList: true
  title: 登录
  constant: true
  layout: false
</route>

<script lang="ts" setup name="Login">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { useI18n } from 'vue-i18n'
import IkingImageValid from 'iking-image-valid'
import useUserStore from '@g/store/modules/user'
import useSettingsStore from '@g/store/modules/settings'
import { ikStore } from 'iking-utils'
import type { tenant } from './interface'
import LoginRegister from './LoginRegister.vue'
import LoginReset from './LoginReset.vue'
import LoginPhone from './LoginPhone.vue'
import LoginWxdd from './LoginWxdd.vue'
import loginType from './login-type'
import SelectionTenant from './SelectionTenant.vue'
import useSocketStore from '@/global/store/modules/socket'
import { tenantApi } from '@/MainApp/apis/tenant'
import { systemConfig } from '@/system.config'

const {
  forgetPassword,
  register,
  remberMe,
  loginType: loginTypes
} = systemConfig.loginTools

const loginImageValidate = {
  background: '#F2F5F7',
  backgroundDark: '#2B2B40',
  height: 48,
  codeColor: ['#F628E2'],
  ...systemConfig.loginImageValidate
}

const loginBg = `url(/system-config/${systemConfig.loginBg})`
const loginBgDark = `url(/system-config/${systemConfig.loginBgDark})`

ElMessage.closeAll()

const route = useRoute()
const router = useRouter()

const userStore = useUserStore()
// 返回登录页时，关闭socket
const socketStore = useSocketStore()
socketStore.closeScoket()

const { settings } = useSettingsStore()
const { msgError } = useMessage()

const { t } = useI18n()

const isDark = computed(() => settings.app.colorScheme === 'dark')

// 表单类型，login 登录，register 注册，reset 重置密码
const formType = ref('login')
const loading = ref(false)
const redirect = ref(route.query.redirect?.toString() ?? '/')

const activeType = ref(loginType[0].icon)
const isPassword = computed(() => activeType.value === loginType[0].icon)
const imageCode = ref()

// 登录
const loginFormRef = ref<FormInstance>()
const remAccount = ikStore.local.getItem(ELocal.REMBER)
const loginForm = ref({
  account: remAccount?.account || '',
  password: remAccount ? window.atob(remAccount.password) : '',
  code: '',
  remember: ikStore.local.has(ELocal.REMBER)
})
/**
 * @description: 登录校验条件
 */
const loginRules = ref<FormRules>({
  account: [{ required: true, trigger: 'blur', message: '请输入用户名' }],
  password: [
    { required: true, trigger: 'blur', message: '请输入密码' },
    { min: 6, max: 18, trigger: 'blur', message: '密码长度为6到18位' }
  ],
  code: [
    {
      required: true,
      trigger: 'blur',
      validator: (rule, value, cb) => {
        if (!value)
          cb('请输入验证码')
        else if (value !== imageCode.value)
          cb('验证码错误')
        else cb()
      }
    }
  ]
})
const showTenant = ref(userStore.showTenant)
const setCode = (code: string) => {
  imageCode.value = code
}
const tenantList = ref<any>(null)
const userTenant = async (params: any) => {
  // await tenantApi.addUserTenant(params)
}
const getLoginUser = async () => {
  const { success, msg } = await tenantApi.getLoginUser()
  if (!success)
    msgError(msg)
}

const queryAllDic = async () => {
  try {
    await userStore.getUserSetting()
    await userStore.getAllDiction()
  }
  catch (error) {
    console.info('error', error)
  }
}
const queryTenant = async () => {
  const res = await userStore.queryTenant()
  if (res?.success) {
    tenantList.value = res?.data || null
    try {
      if (res?.data?.length === 1) {
        if (res?.data[0].status === 'NORMAL') {
          ikStore.local.setItem(ELocal.TENANT, res?.data[0])
          userStore.tenant = res?.data[0]
          await userTenant(res?.data[0]?.code)
          await getLoginUser()
          await queryAllDic()
          if (!userStore.showTenant) {
            router.push(redirect.value)
            return
          }
        }
        else {
          showTenant.value = true
        }
      }
      else if (res?.data?.length > 1) {
        const loginTenant = res?.data.find(
          (item: any) => item.recent === true
        )
        if (loginTenant) {
          userStore.tenant = loginTenant
          ikStore.local.setItem(ELocal.TENANT, loginTenant)
          await userTenant(loginTenant?.code)
          await getLoginUser()
          await queryAllDic()
          if (!userStore.showTenant) {
            router.push(redirect.value)
            return
          }
        }
      }
    }
    catch (error) {

    }

    showTenant.value = true
  }
  else {
    res?.msg && msgError(res?.msg)
    showTenant.value = false
  }
}

function handleLogin() {
  loginFormRef.value
    && loginFormRef.value.validate(valid => {
      if (valid) {
        loading.value = true
        userStore
          .login(
            loginForm.value,
            formType.value === 'login' ? 'password' : formType.value
          )
          .then(async res => {
            if (res?.success) {
              if (loginForm.value.remember) {
                ikStore.local.setItem(ELocal.REMBER, {
                  account: loginForm.value.account,
                  password: window.btoa(loginForm.value.password || '')
                })
                // showTenant.value = true
              }
              else {
                ikStore.local.removeItem(ELocal.REMBER)
              }
              await queryTenant()
              // router.push(redirect.value)
              loading.value = false
            }
            else {
              loading.value = false
            }
          })
          .catch(() => {
            loading.value = false
          })
      }
    })
}

const handChangeLoginType = (ik: { type: string; }) => {
  if (['login', 'password'].includes(ik.type))
    showTenant.value = false

  formType.value = ik.type === 'password' ? 'login' : ik.type
}
const changeTenant = async (item: tenant) => {
  if (item.normal) {
    ikStore.local.setItem(ELocal.TENANT, item)
    userStore.tenant = item
    await userTenant(item?.code)
    await getLoginUser()
    userStore.showTenant = false
    router.push(redirect.value)
  }
}
const changeTenantBack = () => {
  userStore.showTenant = false
  showTenant.value = false
  ElMessage.info(t('app.logout'))
  userStore.logout().then(() => {
    router.push({
      name: 'login'
    })
  })
}
onMounted(() => {
  if (userStore.showTenant) {
    // const data = ikStore.local.getItem(ELocal.USER_INFO)
    queryTenant()
  }
  const { pkg } = __SYSTEM_INFO__
  // 检查依赖版本是否更新
  const pIal = pkg.devDependencies['iking-assets-locales']
  const pIgm = pkg.devDependencies['iking-global-mainapp']
  if (pIal !== localStorage.getItem('iking-assets-locales') || pIgm !== localStorage.getItem('iking-global-mainapp')) {
    localStorage.removeItem(ELocal.IK_SVG)
    localStorage.setItem('iking-assets-locales', pIal)
    localStorage.setItem('iking-global-mainapp', pIgm)
  }
})

watch(
  () => showTenant,
  item => {
    if (item && userStore.showTenant) {
      // const data = ikStore.local.getItem(ELocal.USER_INFO)
      queryTenant()
    }
  }
)

const checkActive = (type: string) => {
  return formType.value === (type === 'password' ? 'login' : type)
}

const resetBg = (url: string) => {
  return `/system-config/${isDark.value ? 'login-dark' : 'login'}/${url}`
}
</script>

<template>
  <div>
    <div class="bg-banner">
      <!-- 兼容只有背景图的情况 -->
      <div v-if="!systemConfig.loginOnlyBg" class="login-animation">
        <div class="out-border background-img">
          <img class="process" :src="resetBg('icon-流程@2x.webp')">
          <img class="mian-ban" :src="resetBg('面板@2x.webp')">
          <img class="logo" :src="resetBg('字母p@2x.webp')">

          <img class="absolute lo-icon-user" :src="resetBg('icon-用户@2x.webp')">
          <img class="absolute lo-icon-approve" :src="resetBg('icon-审批@2x.webp')">
          <img class="absolute lo-icon-system" :src="resetBg('icon-系统@2x.webp')">
          <img class="absolute lo-icon-phone" :src="resetBg('手机@2x.webp')">
          <img class="absolute lo-icon-cloud" :src="resetBg('云@2x.webp')">
        </div>
      </div>
    </div>
    <IkI18nSelector v-if="systemConfig?.tools?.i18n" class="i18n-selector">
      <el-icon>
        <IkSvgIcon name="i-ri:translate" />
      </el-icon>
    </IkI18nSelector>
    <div id="login-box-parent">
      <div v-show="!showTenant" id="login-box">
        <el-form
          v-if="formType === 'login' && isPassword"
          ref="loginFormRef"
          :model="loginForm"
          :rules="loginRules"
          class="login-form"
          autocomplete="on"
        >
          <div class="title-container">
            <h3 class="title">
              <!-- {{ t("app.loginTitle") }} -->
              {{ systemConfig.loginTitle }}
            </h3>
          </div>
          <div>
            <el-form-item prop="account">
              <el-input
                v-model.trim="loginForm.account"
                :placeholder="t('app.account')"
                type="text"
                tabindex="1"
                clearable
                autocomplete="on"
                @keyup.enter="handleLogin"
              >
                <template #prefix>
                  <el-icon size="18">
                    <IkSvgIcon name="iksvg_yonghu" />
                  </el-icon>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item prop="password">
              <el-input
                ref="loginPasswordRef"
                v-model.trim="loginForm.password"
                type="password"
                :placeholder="t('app.password')"
                tabindex="2"
                clearable
                autocomplete="new-password"
                show-password
                @keyup.enter="handleLogin"
              >
                <template #prefix>
                  <el-icon size="18">
                    <IkSvgIcon name="iksvg_suoping" />
                  </el-icon>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item prop="code">
              <el-input
                v-model.trim="loginForm.code"
                :placeholder="t('app.code')"
                type="text"
                clearable
                class="code-img"
                :maxlength="4"
                tabindex="3"
                @keyup.enter="handleLogin"
              >
                <template #prefix>
                  <el-icon size="18">
                    <IkSvgIcon name="iksvg_xiaoyanma" />
                  </el-icon>
                </template>
              </el-input>
              <IkingImageValid
                ref="refValid"
                :option="{
                  ...loginImageValidate,
                  background: isDark ? loginImageValidate.backgroundDark : loginImageValidate.background,
                }"
                @change="setCode"
              />
            </el-form-item>
          </div>
          <div class="flex-bar">
            <el-checkbox
              v-if="remberMe"
              v-model="loginForm.remember"
              tabindex="4"
            >
              {{ t('app.rememberMe') }}
            </el-checkbox>
            <el-link
              v-if="forgetPassword"
              type="primary"
              :underline="false"
              @click="formType = 'reset'"
            >
              {{ t('app.forgetPassword') }}?
            </el-link>
          </div>
          <el-button
            :loading="loading"
            type="primary"
            size="large"
            tabindex="4"
            style="width: 100%"
            @click.prevent="handleLogin"
          >
            {{ t('app.login') }}
          </el-button>
          <div v-if="register" class="sub-link">
            <span class="text">{{ t('app.noAccount') }}?</span>
            <el-link
              type="primary"
              :underline="false"
              @click="formType = 'register'"
            >
              {{ t('app.createAccount') }}
            </el-link>
          </div>
        </el-form>
        <LoginRegister
          v-else-if="formType === 'register'"
          @update:formType="formType = $event"
        />
        <LoginReset
          v-else-if="formType === 'reset'"
          @update:formType="formType = $event"
        />
        <LoginPhone
          v-else-if="formType === 'phone'"
          @update:formType="formType = $event"
        />
        <LoginWxdd
          v-else-if="['wx', 'dd'].includes(formType)"
          :is-wx="formType === 'wx'"
        />
      </div>
      <div v-show="showTenant" id="login-box" class="tenant-box">
        <div class="title-container">
          <h3 class="title">请选择系统</h3>
        </div>
        <SelectionTenant
          class="login-form"
          :tenant-list="tenantList"
          @onChange="changeTenant"
        />
        <div class="sub-link boo-ten">
          <el-link type="primary" :underline="false" @click="changeTenantBack">
            {{ t('app.logout') }}
          </el-link>
        </div>
      </div>
      <div
        v-show="
          ['login', 'phone', 'wx', 'dd'].includes(formType)
            && !showTenant
            && loginTypes.length
        "
        class="login-types"
      >
        <el-divider>{{ t('app.loginType') }}</el-divider>
        <div class="flex flex-row justify-around">
          <template v-for="ik in loginType" :key="ik.icon">
            <IkSvgIcon
              v-if="loginTypes.includes(ik.type)"
              :name="ik.icon"
              pop
              :title="ik.name"
              show-bg
              :size="22"
              :type="checkActive(ik.type) ? 'primary' : ''"
              :class="`login-icon ik ${ik.icon} ${
                checkActive(ik.type) ? 'active' : null
              }`"
              @click="handChangeLoginType(ik)"
            />
          </template>
        </div>
      </div>
    </div>

    <IkCopyright />
  </div>
</template>

<style lang="scss" scoped>
@import './login';

.background-img{
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-position: center;
}

:root.dark {
  .bg-banner {
    background-image: v-bind(loginBgDark);

    .out-border{
      background-image: url('/system-config/login-dark/线框@2x.webp');

      &::before{
        background-image: url('/system-config/login-dark/底座.webp');
      }
    }
  }

  #login-box-parent{
    background-color: rgba(30 30 45 / 60%);

    :deep(.el-divider__text){
      background-color: transparent;
    }

    #login-box{
      :deep(.el-form-item ) .el-input__wrapper {
        background: var(--ik-input-bg);

        &.is-focus {
            background-color: var(--ik-input-focus-bg);
        }
      }
    }
  }
}

.bg-banner {
  position: fixed;
  z-index: 0;
  width: 100%;
  height: 100%;
  background-image: v-bind(loginBg);
  background-size: 100% 100%;

  .login-animation {
    width: 50vw;
    height: 70vh;
    left: 10%;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);

    .out-border {
      display: inline-block;
      position: absolute;
      width: 100vh;
      height: 51vh;
      background-image: url('/system-config/login/线框@2x.webp');
      left: 50%;
      top: 50%;
      transform: translate(-50%, -25%);

      &::before{
        content: '';
        display: inline-block;
        background-image: url('/system-config/login/底座.webp');
        position: absolute;
        left: 55%;
        width: 70vh;
        height: 70vh;
        transform: translate(-50%, -3%);
        background-size: 100% 100%;
        background-repeat: no-repeat;
        background-position: center;
      }

      .logo{
        z-index: 2;
        position: absolute;
        left: 45%;
        bottom: 48%;
        width: 130px;
        // animation: logoani 2s infinite alternate;
      }

      .process{
        position: absolute;
        left: 3%;
        bottom: 74%;
        width: 100px;
      }

      .mian-ban{
        left: 20%;
        position: absolute;
        bottom: 64%;
        width: 230px;
      }

      .lo-icon-user{
        right: 25%;
        width: 100px;
        bottom: 57%;
        animation: move 2s infinite .75s alternate;
        z-index: 0;
      }

      .lo-icon-approve{
        width: 80px;
        top: 33%;
        left: 29%;
        animation: move 2s infinite alternate;
        z-index: 3;
      }

      .lo-icon-system{
        width: 80px;
        right: 42%;
        top: -15%;
        z-index: -1;
      }

      .lo-icon-phone{
        width: 50px;
        left: 19%;
        top: 25%;
      }

      .lo-icon-cloud{
        right: 24%;
        top: -16%;
        width: 100px;
        animation: move 1s infinite alternate;
      }

      @keyframes move {
        0% {
          transform: translateY(30%);
        }

        100% {
          transform: translateY(0);
        }
      }

      @keyframes top-to-bottom {
        0% {
          width: 100px;
          right: 25%;
          bottom: 57%;
        }

        100% {
          right: 34%;
          width: 74px;
          bottom: 54%;
        }
      }

      @keyframes logoani {
        0% {
          left: 45%;
          bottom: 49%;
          width: 132px;
        }

        100% {
          left: 42%;
          bottom: 58%;
          width: 145px;
        }
      }

      @keyframes bottom-to-top {
        0% {
          top: 33%;
          left: 29%;
        }

        100% {
          top: 38%;
          left: 45%;
        }
      }
    }
  }
}

.tenant-box {
  flex-direction: column;

  .boo-ten {
    margin: 20px 0 !important;
  }

  .title-container {
    padding: 20px 20px 0;
    position: relative;

    .title {
      font-size: 1.3em;
      color: var(--el-text-color-primary);
      font-weight: bold;
    }
  }

  .tenant-back {
    padding: 20px 20px 0;
  }
}
</style>
